﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Dx.DDD.Repositories
{
    public static class DbContextExt
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TContext"></typeparam>
        /// <param name="builderAction"></param>
        /// <param name="optionsAction"></param>
        /// <param name="enableWork">是否启用工作单元</param>
        /// <param name="poolSize"></param>
        /// <returns></returns>
        public static IServiceCollection AddDbContext<TContext,TSunContext>(this IServiceCollection builderAction,Action<DbContextOptionsBuilder> optionsAction,bool enableWork=false, int poolSize = 1024) where TContext : DbContext
            where TSunContext : DbContext, TContext
        {
            if (enableWork)
            {
                AddUnitOfWork();
            }
            //builderAction.AddSingleton<DbContextFactory>();
            builderAction.AddDbContextPool<TContext, TSunContext>(optionsAction, poolSize);
            return builderAction;
        }
        /// <summary>
        /// 将UnitOfWorkAttribute提前加入字典中
        /// </summary>
        private static void AddUnitOfWork() 
        {
            var types = GetAllControllers();

            foreach (var typeinfo in types)
            {
                var methods = typeinfo.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
                foreach (var method in methods)
                {
                    var name = method.DeclaringType?.FullName + "." + method.Name;
                    var unitOfWorks = method.GetCustomAttributes<UnitOfWorkAttribute>();
                    if (unitOfWorks != null && unitOfWorks.Count() != 0) 
                    {
                        foreach (var unitOfWork in unitOfWorks) 
                        {
                            unitOfWork.Add(name);
                        }
                    } 
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<Type> GetAllControllers()
        {
            // 获取当前应用程序域中的所有程序集
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            // 遍历所有程序集，查找继承自 ControllerBase 的类
            var controllerTypes = assemblies
                .SelectMany(assembly => assembly.GetTypes())
                .Where(type => type.IsSubclassOf(typeof(ControllerBase)) && !type.IsAbstract);
            return controllerTypes;
        }
    }
}
